﻿#include "Sort.h"

void PrintArray(int* a, int n)
{
	for (int i = 0; i < n; ++i)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

// 时间复杂度(最坏)：O(N^2) -- 逆序
// 时间复杂度(最好)：O(N) -- 顺序有序
//void InsertSort(int* a, int n)
//{
//	for (int i = 1; i < n; ++i)
//	{
//		// [0, end] 有序，插入tmp依旧有序
//		int end = i - 1;
//		int tmp = a[i];
//
//		while (end >= 0)
//		{
//			if (a[end] < tmp)
//			{
//				a[end + 1] = a[end];
//				--end;
//			}
//			else
//			{
//				break;
//			}
//		}
//
//		a[end + 1] = tmp;
//	}
//}
void InsertSort(int* a, int n)
{
	for (int i = 0; i < n-1; ++i)
	{
		// [0, end] 有序，插入tmp依旧有序
		int end = i;
		int tmp = a[i+1];

		while (end >= 0)
		{
			if (a[end] > tmp)
			{
				a[end + 1] = a[end];
				--end;
			}
			else
			{
				break;
			}
		}

		a[end + 1] = tmp;
	}
}


/*for (int j = 0; j < gap; j++)
	{
		for (int i = j; i < n - gap; i += gap)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > tmp)
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}

			a[end + gap] = tmp;
		}
	}*/

void ShellSort(int* a, int n)
{
	// 初始化gap值为数组长度
	int gap = n;

	// 当gap大于1时，进行希尓排序的预排序阶段
	while (gap > 1)
	{
		// 更新gap值，这里使用的是希尓增量序列：h(k) = ⌊h(k-1)/3⌋ + 1
		// 这种增量序列的选择是为了更快地收敛到直接插入排序
		// 其他常用的增量序列有 h(k) = ⌊h(k-1)/2⌋
		gap = gap / 3 + 1;

		// 对所有间隔为gap的元素进行部分排序
		for (int i = 0; i < n - gap; ++i)
		{
			// 设定一个起始位置end，并取下一个待插入的元素tmp
			int end = i;
			int tmp = a[end + gap];

			// 从end开始向前比较，寻找tmp应该插入的位置
			while (end >= 0)
			{
				if (a[end] > tmp)
				{
					// 如果当前位置的元素比tmp大，则将该元素向后移动
					a[end + gap] = a[end];
					end -= gap;  // 继续向前比较
				}
				else
				{
					// 如果当前位置的元素小于等于tmp，则找到了插入位置，退出循环
					break;
				}
			}

			// 将tmp插入到正确的位置
			a[end + gap] = tmp;
		}
	}

	// 当gap等于1时，相当于执行了一次直接插入排序，完成整个数组的排序
}

void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; ++j)
	{
		bool exchange = false;
		for (int i = 1; i < n-j; i++)
		{
			if (a[i - 1] > a[i])
			{
				int tmp = a[i];
				a[i] = a[i - 1];
				a[i - 1] = tmp;

				exchange = true;
			}
		}

		if (exchange == false)
		{
			break;
		}
	}
}

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void SelectSort(int* a, int n)
{
	int begin = 0, end = n - 1;
	while (begin < end)
	{
		int maxi = begin, mini = begin;
		for (int i = begin; i <= end; i++)
		{
			if (a[i] > a[maxi])
			{
				maxi = i;
			}

			if (a[i] < a[mini])
			{
				mini = i;
			}
		}

		Swap(&a[begin], &a[mini]);
		// 如果maxi和begin重叠，修正一下即可
		if (begin == maxi)
		{
			maxi = mini;
		}

		Swap(&a[end], &a[maxi]);

		++begin;
		--end;
	}
}